package com.ly.mpayment.core.util;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import net.sf.ehcache.Cache;
import net.sf.ehcache.CacheManager;
import net.sf.ehcache.Element;
import net.sf.ehcache.search.Query;
import net.sf.ehcache.search.Result;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;


/**
 * 工具类 - 缓存管理. <br>
 * 处理缓存的添加、更新级删除.
 */
public class AppCacheManager {

	private static  final String CACHE_NAME = "baseData";
	/** LOG. */
	private final static Log log = LogFactory.getLog(AppCacheManager.class);
	
	private final static  String SZ_INTERFACE = "CacheKey";
	/** 缓存Manager实例. */
	private static CacheManager manager;
	static {
		try {
			manager = CacheManager.getInstance();
			if (null == manager) {
				manager = CacheManager.create();
			}
		} catch (Exception e) {
			log.error("缓存初始化失败!", e);
		}
	}

	/**
	 * 从缓存中获取对象.
	 * 
	 * @param cache_name
	 *            缓存名称，如ehcache.xml中 <br>
	 *            产品实体配置的name：com.handou.ehcache.Product
	 * @param key
	 *            一般采用缓存对象的主键（具有唯一性的字符串）
	 * @return 缓存对象
	 */
	@SuppressWarnings("deprecation")
	private static Serializable getObjectCached(String cache_name,
			Serializable key) {
		Cache cache = getCache(cache_name);
		if (cache != null) {
			try {
				Element elem = cache.get(key);
				if (elem != null && !cache.isExpired(elem))
					return elem.getValue();
			} catch (Exception e) {

				log.error("Getcache(" + cache_name + ") of " + key

				+ "failed.", e);
			}
		}

		return null;
	}
	
	/**
	 * 从缓存中获取对象.
	 * 
	 * @param cache_name
	 *            缓存名称，如ehcache.xml中 <br>
	 *            产品实体配置的name：com.handou.ehcache.Product
	 * @param key
	 *            一般采用缓存对象的主键（具有唯一性的字符串）
	 * @return 缓存对象
	 */
	@SuppressWarnings("unchecked")
	public static <T extends Serializable> T getObjectCached(Class<T> clazz, Serializable key) {
		return (T)getObjectCached(clazz.getName(), key);
	}

	/**
	 * 把对象放入缓存中
	 * 
	 * @param cache_name
	 *            缓存名称，如ehcache.xml中 <br>
	 *            产品实体配置的name：com.handou.ehcache.Product
	 * @param key
	 *            一般采用缓存对象的主键（具有唯一性的字符串）
	 * @param value
	 *            需要加入缓存的实体对象，如new <br>
	 *            一个的com.handou.ehcache.Product对象
	 */
	public  synchronized static void putObjectCached(String cache_name,
			Serializable key, Serializable value) {
		Cache cache = getCache(cache_name);
		if (cache != null) {
			try {
				cache.remove(key);
				Element elem = new Element(key, value);
				cache.put(elem);
			} catch (Exception e) {
				log.error("putcache(" + cache_name + ") of " + key + "failed.", e);
			}
		}
	}
	
	/**
	 * 将对象集合缓存到缓存中
	 * @param cache_name
	 * @param list
	 */
	public static void cacheAll(String cache_name,Collection<Object> list){
		Cache cache = getCache(cache_name);
		for(Object entity : list){
			cache.put(new Element(entity,entity ));
		}
	}
	
	/**
	 * 一次缓存所有
	 * @param list
	 */
	@SuppressWarnings({ "rawtypes", "unchecked" })
	public static void cacheAll(List list){
		String key  = list.get(0).getClass().getName();
		cacheAll(key, list);
	}
	
	@SuppressWarnings({ "rawtypes", "unchecked" })
	public static void cacheBaseDataAll(List list){
		
		cacheAll(CACHE_NAME, list);
	}
	
	/**
	 * 根据缓存名称获取缓存中的全部数据
	 * @param clazz
	 * @return
	 */
	public static List<Object> getAll(Class<Serializable> clazz){
		
		Cache cache = getCache(clazz.getName());
		
		Query query = cache.createQuery();
		query.includeValues();
		List<Result> resultList = query.execute().all();
		List<Object> list = new ArrayList<Object>();
		for(Result result : resultList){
			list.add(result.getValue());
		}
		return list;
	}
	
	/**
	 * 通过缓存名称获取缓存.
	 * @param cacheName - 缓存名称
	 * @return cache - 缓存
	 */
	private final static Cache getCache(String arg) {
		return manager.getCache(arg.toString());
	}


	/**
	 * 判断是否实现某一个接口
	 * @param clazz
	 * @return
	 */
	@SuppressWarnings({ "rawtypes", "unused" })
	private  static boolean isInterface(Class clazz){
		Class[] faceArray  = clazz.getInterfaces();
		for(Class face  : faceArray){
			if(face.getName().equals(SZ_INTERFACE)){
				return true;
			}
		}
		return false;
		
	}

	

}
